Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

ANGLE support #1017

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

ANGLE support #1017

wants to merge 4 commits into from

Conversation

Alovchin91
Copy link
Contributor

@Alovchin91 Alovchin91 commented Jan 30, 2025

This change adds ANGLE renderer support to Skiko.

ANGLE project translates OpenGL ES API calls to the native platform's graphics API. This is mostly useful on Windows where ANGLE provides the Direct3D 11 backend.

Right now, there is a gap in Skiko's graphics support. On Windows ARM, Skia doesn't support OpenGL yet. At the same time, some GPUs, like Parallels or VMware virtual GPUs, don't support DirectX 12. This means Skiko falls back to the slow software rendering on those GPUs. ANGLE solves this problem by providing an easy-to-use DirectX 11 backend.

In addition, ANGLE is used by Chromium-based browsers and apps, so we expect it to be more stable than Skia's DirectX backend.

@igordmn igordmn self-requested a review January 30, 2025 10:50
@@ -43,7 +43,7 @@ case $SKIA_TARGET in
;;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It will be good if we can include Angle as a jar via skiko-awt-runtime-angle-$platform

Copy link
Contributor Author

@Alovchin91 Alovchin91 Jan 31, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Let me see if I can figure this out

@igordmn igordmn self-requested a review January 31, 2025 13:38
@Alovchin91 Alovchin91 force-pushed the alovchin/angle branch 4 times, most recently from b951351 to 87790e5 Compare February 7, 2025 15:34
@Alovchin91 Alovchin91 marked this pull request as ready for review February 7, 2025 15:42
@@ -127,7 +132,7 @@ object SkikoProperties {
when(hostOs) {
OS.MacOS -> return GraphicsApi.METAL
OS.Linux -> return GraphicsApi.OPENGL
OS.Windows -> return GraphicsApi.DIRECT3D
OS.Windows -> return GraphicsApi.ANGLE
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Skiko without Angle prints an error into console:

[SKIKO] warn: Fallback to next API
org.jetbrains.skiko.RenderException: Failed to load ANGLE library: org.jetbrains.skiko.RenderException: Native exception in [Java_org_jetbrains_skiko_AngleSupport_1jvmKt_loadAngleLibraryWindows], code 126: The specified module could not be found.

We should check overhead of loading Angle without dlls.

If it is almost zero - replace RenderException by OptionalRenderApiException : RenderException and ignore it without printing.

Otherwise add something skiko.renderApi.fallbackChain that also specifies the default (first one).

private external fun disposeDevice(device: Long)

@Suppress("unused")
class AngleRedrawerException(message: String) : RuntimeException(message)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why not reuse RenderException?

return eglGetProcAddress(procname);
}

JNIEXPORT jstring JNICALL Java_org_jetbrains_skiko_AngleApi_glGetString(JNIEnv *env, jobject object, jint value)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Better to Move to AngleApi.cc (in the other file too)

package org.jetbrains.skiko

/**
* Load OpenGL library into memory.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Kdoc should be rewritten

?: throw RenderException("Failed to create ANGLE device.")
}
adapterName.let { adapterName ->
if (adapterName == null || !isVideoCardSupported(GraphicsApi.ANGLE, hostOs, adapterName)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the OpenGLRedrawer it is adapterName != null && , just to pass a valid value to isVideoCardSupported, not prohibit null adapterName. Can we use the same logic? Or it is better to have this?

TCHAR libEGL[MAX_PATH] = TEXT("");
TCHAR libGLESv2[MAX_PATH] = TEXT("");
HMODULE hmodule = nullptr;
THROW_IF_NULL(GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where should I put dll's in case I run a Java library?

Worked only after I packaging via jpackage, and placing the libs near the jars. But not sure how it should work without it, for example, when I run via Gradle that defines a classpath in different cached folders.

@@ -139,8 +144,8 @@ object SkikoProperties {
OS.MacOS -> listOf(GraphicsApi.METAL, GraphicsApi.SOFTWARE_COMPAT)
OS.Windows -> when (hostArch) {
// Skia isn't properly tested on OpenGL and Windows ARM (https://groups.google.com/g/skia-discuss/c/McoclAhLpvg?pli=1)
Arch.Arm64 -> listOf(GraphicsApi.DIRECT3D, GraphicsApi.SOFTWARE_FAST, GraphicsApi.SOFTWARE_COMPAT)
else -> listOf(GraphicsApi.DIRECT3D, GraphicsApi.OPENGL, GraphicsApi.SOFTWARE_FAST, GraphicsApi.SOFTWARE_COMPAT)
Arch.Arm64 -> listOf(GraphicsApi.ANGLE, GraphicsApi.DIRECT3D, GraphicsApi.SOFTWARE_FAST, GraphicsApi.SOFTWARE_COMPAT)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is other OS support planned? I looked at https://skia.org/docs/user/special/angle/, and it seems only Linux additionally mentioned. 4 years ago I thought it was also macOs. Maybe it was deprecated, or I thought wrongly.

import org.jetbrains.skiko.*
import org.jetbrains.skiko.context.AngleContextHandler

internal class AngleRedrawer(
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tested FPS manually, and have FPS dropped from 80 to 69 (DIRECT3D -> ANGLE).

I suspected dwmFlush. Removing it, and enabling eglSwapInterval(angleDevice->display, 1) increased FPS to 93.

I think we can use eglSwapInterval here. Because it is not a real opengl, just translated to DirectX, right? When in the past I tested real OpenGL, vsync was unstable with SwapInterval compared to dwmFlush.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is one catch though, when I maximize the DirectX window, my system somehow optimises this case and increases the FPS (from mentioned 80 to 90).

But with the Angle implementation, this optimisation doesn't work, and FPS decreases from 93 to 77 🤔

Not sure what is this optimization. Prioritisation? Simplified composition? gpu boost? Needs investigation

AngleDevice *angleDevice = new AngleDevice();
angleDevice->window = hwnd;
angleDevice->device = hdc;
angleDevice->display = getAngleEGLDisplay(angleDevice->device);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should test how if FPS always equals refresh rate when we move a window from one display to another with different refresh rate (after removing dwmFlush)

THROW_IF_NULL(LoadLibrary(libGLESv2));
}
}

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have d3dcompiler_47.dll already inside my system32 folder. Not sure that it is the same on other systems though.

Works without this one: https://github.com/Alovchin91/angle-pack/releases/tag/7fea539cc9

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants